package org.acompanhamento.domain;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Transient;

import jmine.tec.aom.domain.AbstractPropertyValue;
import jmine.tec.aom.domain.Propertized;
import jmine.tec.aom.domain.Property;
import jmine.tec.aom.util.BasePropertyHandler;
import bancosys.tec.persist.bussobj.PersistableBusinessObject;

/**
 * 
 * @author lundberg
 *
 */
public abstract class PropertizedEntity extends PersistableBusinessObject implements Propertized {

    private Propertized propertyHandler;

    /**
     * @return propertyHandler
     */
    @Transient
    protected Propertized getPropertyHandler() {
        if (this.propertyHandler == null) {
            this.propertyHandler = this.doGetPropertyHandler();
        }
        return this.propertyHandler;
    }

    /**
     * @return the Propertized that will handle {@link Property} and {@link AbstractPropertyValue} for this {@link Propertized}.
     */
    protected Propertized doGetPropertyHandler() {
        return new BasePropertyHandler(getEntityProperties(), new HashSet<AbstractPropertyValue<?>>());
    }

    /**
     * Set of properties used by this entity
     * @return set of properties
     */
    @Transient
    protected abstract Set<Property> getEntityProperties();

	/**
     * {@inheritDoc}
     */
    @Transient
    public Set<Property> getProperties() {
        return this.getPropertyHandler().getProperties();
    }

    /**
     * {@inheritDoc}
     */
    @Transient
    public Set<Property> getRealProperties() {
        return this.getPropertyHandler().getRealProperties();
    }

    /**
     * {@inheritDoc}
     */
    @Transient
    public Set<Property> getSyntheticProperties() {
        return this.getPropertyHandler().getSyntheticProperties();
    }

    /**
     * {@inheritDoc}
     */
    @Transient
    public Set<AbstractPropertyValue<?>> getPropertyValues() {
        return this.getPropertyHandler().getPropertyValues();
    }

    /**
     * {@inheritDoc}
     */
    @Transient
    public Propertized getParent() {
        return this.getPropertyHandler().getParent();
    }

    /**
     * {@inheritDoc}
     */
    @Transient
    public Property getPropertyByName(String name) {
        return this.getPropertyHandler().getPropertyByName(name);
    }

    /**
     * {@inheritDoc}
     */
    @Transient
    public Property getPropertyByMnemonic(String mnemonic) {
        return this.getPropertyHandler().getPropertyByMnemonic(mnemonic);
    }

    /**
     * {@inheritDoc}
     */
    @Transient
    public AbstractPropertyValue<?> getPropertyValue(Property property) {
        return this.getPropertyHandler().getPropertyValue(property);
    }

    /**
     * {@inheritDoc}
     */
    @Transient
    @SuppressWarnings("rawtypes")
	public void removePropertyValue(AbstractPropertyValue propertyValue) {
        this.getPropertyHandler().removePropertyValue(propertyValue);
    }

    /**
     * {@inheritDoc}
     */
    @Transient
    @SuppressWarnings("rawtypes")
    public void addPropertyValue(AbstractPropertyValue propertyValue) {
        this.getPropertyHandler().addPropertyValue(propertyValue);
    }

}
